import logging
from collections import deque

from PySide6 import QtCore
from PySide6.QtCore import Qt, QPointF, Signal, QTimer
from PySide6.QtGui import QPen, QBrush
from PySide6.QtWidgets import QGraphicsItem, QGraphicsWidget, QColorDialog, QGraphicsRectItem

from 程序核心代码.mvvm重构.基础定义.基础图形项.节点图形项 import 容器边框颜色, 容器背景颜色

# 配置日志记录器
logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(levelname)s - %(message)s')
日志记录器 = logging.getLogger(__name__)

class 容器组件基础图形项(QGraphicsWidget):
    容器内容改变信号 = Signal()
    添加图形项信号 = QtCore.Signal(QGraphicsRectItem)# 内容改变信号，通知容器内容改变，重新检查节点大小
    移除图形项信号 = QtCore.Signal(QGraphicsRectItem)
    def __init__(self, x, y, 宽度, 高度, 父项=None):

        super().__init__(父项)
        self.父项 = 父项
        self.调试模式 = False
        # 设置日志等级
        if self.调试模式:
            日志记录器.setLevel(logging.DEBUG)
            日志记录器.debug(f"{self.__class__.__name__}调试模式已开启")
        else:
            日志记录器.setLevel(logging.ERROR)  # 只显示警告及以上级别的日志

        日志记录器.info("容器组件基础图形项创建")
        日志记录器.info(f"父项: {self.父项}")
        self.setPos(x, y)
        self.setGeometry(0, 0, 宽度, 高度)

        # 设置边框和背景颜色
        self.边框颜色 = 容器边框颜色
        self.背景颜色 = 容器背景颜色
        self.正在调整大小 = False
        self.最小宽度 = 1000  # 可根据需求调整
        self.最小高度 = 1000
        self.待添加图形项队列 = deque()
        # 设置图形项移动和选择标志（优化的选择）
        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, False)
        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, False)
        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemSendsGeometryChanges, False)
        self.容器内容改变信号.connect(self.计算容器组件最小边界)
        self.添加图形项信号.connect(self.延时添加图形项)
        self.移除图形项信号.connect(self.移除图形项)

    def 计算容器组件最小边界(self):
        """
        动态计算容器内所有子项的边界，并根据最大右下角设置容器边界。
        """
        最大右下角 = QPointF(0, 0)

        # 遍历所有子项，计算每个子项的右下角位置
        for child in self.childItems():
            # 获取子项的矩形边界
            子项边界 = child.boundingRect()
            # 计算子项的右下角位置（左上角 + 尺寸）
            子项右下角 = child.pos() + QPointF(子项边界.width(), 子项边界.height())

            # 更新最大右下角
            最大右下角.setX(max(最大右下角.x(), 子项右下角.x()))
            最大右下角.setY(max(最大右下角.y(), 子项右下角.y()))

        # 计算容器的新最小宽度和高度
        新最小宽度 = 最大右下角.x()
        新最小高度 = 最大右下角.y()
        # 更新最小宽度和高度
        # 两种策略：如果节点是自适应大小，
        if self.最小宽度 != 新最小宽度 or self.最小高度 != 新最小高度:
            self.最小宽度 = 新最小宽度
            self.最小高度 = 新最小高度
            # 设置新的最小宽度和高度
            self.setMinimumWidth(self.最小宽度)
            self.setMinimumHeight(self.最小高度)

    def 获取特定坐标的子图形项(self, 新位置):
        """
        根据给定位置，获取在该位置的子图形项。
        """
        for 子项 in self.childItems():
            if 子项.contains(子项.mapFromParent(新位置)):
                return 子项
        return None

    def paint(self, painter, option, widget=None):
        """
        绘制容器的边框和背景。
        """
        painter.setPen(QPen(self.边框颜色))
        painter.setBrush(QBrush(self.背景颜色))
        painter.drawRect(self.rect())
        日志记录器.debug(f"{self.__class__.__name__}绘制背景和边框")

    def itemChange(self, change, value):
        """
        处理图形项位置或变换变化事件，并通知父项。
        """
        if change in [QGraphicsItem.GraphicsItemChange.ItemPositionChange, QGraphicsItem.GraphicsItemChange.ItemTransformChange]:
            parent = self.parentItem()
            if parent:
                parent.prepareGeometryChange()
        return super().itemChange(change, value)

    def resizeEvent(self, event):
        """
        处理容器大小变化事件，更新容器的几何形状。
        """
        super().resizeEvent(event)
        日志记录器.debug("容器尺寸发生变化，更新几何形状")

    def mousePressEvent(self, event):
        """
        处理鼠标点击事件，控制左键的处理逻辑。
        """
        if event.button() == Qt.MouseButton.LeftButton:
            event.accept()  # 接受事件，防止传递给父项
            日志记录器.debug("左键点击事件已接受")
        else:
            super().mousePressEvent(event)  # 其他情况继续传递事件给父项

    def 打开颜色选择器(self):
        """
        打开颜色选择器对话框，并将用户选择的颜色应用为背景颜色。
        """
        选择的颜色 = QColorDialog.getColor()

        if 选择的颜色.isValid():
            # 如果用户选择了有效的颜色，将背景颜色更新为用户选择的颜色
            日志记录器.info(f"用户选择的颜色: {选择的颜色}")
            self.背景颜色 = 选择的颜色
            self.update()  # 刷新图形项，应用新颜色
    def 检查图形项是否存在(self, 图形项):
        return 图形项 in self.childItems()
    def 批量添加图形项(self, 图形项列表):
        for 图形项 in 图形项列表:
            self.添加图形项(图形项)
    def 添加图形项(self, 图形项):
        图形项.setParentItem(self)
    def 批量移除图形项(self, 图形项列表):
        for 图形项 in 图形项列表:
            self.移除图形项(图形项)
    def 移除图形项(self, 图形项):
        图形项.setParentItem(None)


    def 延时添加图形项(self, 图形项):
        self.待添加图形项队列.append(图形项)
        if not hasattr(self, '定时器') or not self.定时器.isActive():
            self.启动定时器()

    def 启动定时器(self):
        self.定时器 = QTimer(self)
        self.定时器.setSingleShot(True)
        self.定时器.timeout.connect(self.处理待添加图形项)
        self.定时器.start(100)# 延时100ms执行

    def 处理待添加图形项(self):
        while self.待添加图形项队列:
            图形项 = self.待添加图形项队列.popleft()
            self.添加图形项(图形项)